package sample.crawler;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import javafx.scene.control.TableView;
import sample.enums.MapExecCode;
import sample.model.Company;
import sample.utils.HttpRequestor;
import sample.utils.StringUtils;

import java.util.List;
import java.util.concurrent.Callable;

public class BaiduCallable extends BaseCrawler implements Callable<Integer> {

    protected static Boolean firstRequest = true;
    protected static Integer totalPage = 1;
    protected static final Integer pageSize = 20;

    public BaiduCallable()
    {

    }

    public BaiduCallable(String keywords, List<String> exclusiveWords, String area, Boolean filterTel, TableView<Company> qrTable)
    {
        super.keywords = keywords;
        super.exclusiveWords = exclusiveWords;
        super.qrTable = qrTable;
        super.filterTel = filterTel;

        // 百度只支持到市的查询
        String[] areas = area.split(",");
        super.area = areas[1] == null ? areas[0] : areas[1];
    }

    private JSONObject request(Integer pageNo){

        String json = null;
        String url = "http://api.map.baidu.com/place/v2/search?query=" + keywords + "&tag=&region=" + area + "&output=json&ak=RxoisybOPRPMt4vib8q6gmoHrPlptdKZ&page_size="+pageSize+"&page_num=" + pageNo;
        logger.info("[baidu] request url:{}", url);
        try {
            json = new HttpRequestor().doGet(url);
        } catch (Exception e) {
            logger.error("[baidu] send request call exception, url:{}, e:{}", url, e);
            e.printStackTrace();
        }
        JSONObject jsonObject = JSONObject.parseObject(json);

        if(firstRequest) {
            Integer total = jsonObject.getInteger("total");
            if(total == null) {
                totalPage = 0;
            } else {
                totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            }
            logger.info("[baidu] start to reqest, keywords:{}, area:{}, totalPage:{}", keywords, area, totalPage);
            firstRequest = false;
        }

        return jsonObject;
    }

    @Override
    public Integer call() {
        Integer code = MapExecCode.COMPLETE.getCode();
        for (int pageNo = 1; pageNo <= totalPage; pageNo++) {
            logger.info("[baidu] start to request, keywords:{}, area:{}, pageNo:{}", keywords, area, pageNo);
            if(Thread.interrupted()) {
                code = MapExecCode.STOP.getCode();
                break;
            }

            JSONObject jsonObject = request(pageNo);
            logger.info("[baidu] succeed to request, keywords:{}, area:{}, totalPage:{}", keywords, area, totalPage);
            if(jsonObject.getInteger("status") == 401) {
                //MainController.status.setText(jsonObject.getString("message"));
                code = MapExecCode.QUOTA_NOT_ENOUGH.getCode();
                break;
            }
            JSONArray results = jsonObject.getJSONArray("results");
            if(results == null)
            {
                code = MapExecCode.NODATA.getCode();
                break;
            }
            for (Object o : results) {
                JSONObject target = (JSONObject) o;

                // 过滤排除关键字
                String name = target.getString("name");
                if(StringUtils.contains(name, exclusiveWords)) {
                    continue;
                }

                // 过滤空电话
                String tel = target.getString("telephone");
                if(filterTel && StringUtils.isEmpty(tel)) {
                    continue;
                }

                JSONObject location = target.getJSONObject("location");
                StringBuffer locsb = new StringBuffer().append(location.getInteger("lat")).append(",").append(location.getInteger("lng"));

                qrTable.getItems().add(new Company(getIndex() + "", tel , name, target.getString("province")+ target.getString("city") +target.getString("area"), target.getString("address"), "",
                        keywords, "百度", locsb.toString()));

            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                code = MapExecCode.STOP.getCode();
            }
        }
        return code;
    }
}
